package com.closer.server.biz.organization.service.impl;

import com.closer.server.biz.organization.dto.*;
import com.closer.server.biz.organization.dto.vo.OrganizationVO;
import com.closer.server.biz.organization.entity.OrganizationMember;
import com.closer.server.biz.organization.service.OrganizationMemberService;
import com.closer.server.biz.organization.validator.OrganizationValidator;
import com.closer.server.support.exception.ErrorCode;
import com.closer.server.support.exception.ThrowUtils;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.closer.server.biz.organization.entity.Organization;
import com.closer.server.mapper.organization.OrganizationMapper;
import com.closer.server.biz.organization.service.OrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 组织表 服务层实现。
 * @author closer
 */
@Service
@Slf4j
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization>  implements OrganizationService{


    private final OrganizationValidator validator;

    private final OrganizationMemberService memberService;

    public OrganizationServiceImpl(OrganizationValidator validator,OrganizationMemberService memberService) {
        this.validator = validator;
        this.memberService = memberService;
    }

    @Override
    public long create(CreateRequest params) {
        validator.validate(params);
        var organization = Organization.builder()
                .name(params.getName())
                .description(params.getDescription())
                .creatorId(params.getCreatorId())
                .build();
        var result = this.save(organization);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR,"创建组织失败");
        var member = OrganizationMember.builder()
                .organizationId(organization.getId())
                .userId(params.getCreatorId())
                .build();
        var memberResult = memberService.save(member);
        ThrowUtils.throwIf(!memberResult, ErrorCode.OPERATION_ERROR,"添加组织成员失败");
        return organization.getId();
    }

    @Override
    public boolean updateInfo(UpdateRequest params) {
        validator.validate(params);
        var result = this.mapper.updateInfo(params);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR,"更新组织失败");
        return true;
    }

    @Override
    @Transactional
    public boolean leave(LeaveRequest params) {
        validator.validate(params);
        var countsResult = this.mapper.updateRemoveMemberCounts(params.getOrganizationId());
        ThrowUtils.throwIf(!countsResult, ErrorCode.OPERATION_ERROR,"更新组织成员数失败");
        if(memberService.getMemberCounts(params.getOrganizationId())>1){
            var memberResult = memberService.removeById(memberService.getId(params.getId()));
            ThrowUtils.throwIf(!memberResult, ErrorCode.OPERATION_ERROR,"删除组织成员失败");
            if(Objects.equals(this.mapper.existsOrganization(params.getOrganizationId()).getCreatorId(), params.getId())){
                var creatorId= memberService.getEarliestMember(params.getOrganizationId());
                var updateResult = this.mapper.updateCreatorId(params.getOrganizationId(), creatorId);
                ThrowUtils.throwIf(!updateResult, ErrorCode.OPERATION_ERROR,"更新组织创建者失败");
            }
        }else{
            var result = this.removeById(params.getOrganizationId());
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR,"删除组织失败");
            var memberResult = memberService.removeById(memberService.getId(params.getId()));
            ThrowUtils.throwIf(!memberResult, ErrorCode.OPERATION_ERROR,"删除组织成员失败");
        }
        return true;
    }

    @Override
    @Transactional
    public boolean join(JoinRequest params) {
        validator.validate(params);
        var member = OrganizationMember.builder()
                .organizationId(params.getOrganizationId())
                .userId(params.getUserId())
                .build();
        var result = memberService.save(member);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR,"添加组织成员失败");
        var countsResult = this.mapper.updateAddMemberCounts(params.getOrganizationId());
        ThrowUtils.throwIf(!countsResult, ErrorCode.OPERATION_ERROR,"更新组织成员数失败");
        return true;
    }

    @Override
    public Page<OrganizationVO> search(SearchRequest params) {
        validator.validate(params);
        return this.mapper.getOrganizationVOList(params);
    }
}
